﻿using System.Collections.Concurrent;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using MongoDB.Driver;
using WebApplication1.Models;
using WebApplication1.Repository;
using Microsoft.AspNetCore.Http;

namespace WebApplication1.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class AuthController : ControllerBase
    {
        private readonly IConfiguration _configuration;
        private static readonly ConcurrentDictionary<string, string> RefreshTokens = new();

        private readonly UserRepository _repository;

        private readonly IMongoCollection<User> _collection;

     
        public AuthController(IConfiguration configuration, UserRepository repository,IMongoDatabase database)
        {
            _configuration = configuration;
            _repository = repository; // 修复：将 repository 参数赋值给 _repository
            _collection = database.GetCollection<User>("Users");

        }
        
        [HttpPost("login")]
        [AllowAnonymous]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesDefaultResponseType]
        public async Task<IActionResult> Login([FromBody] LoginModel model)
        {
            // 从数据库中查找用户并验证密码
            var user = await _collection.Find(u => u.UserName == model.Username).FirstOrDefaultAsync();
            if (user == null || !VerifyPassword(model.Password, user.Password))
            {
                return Unauthorized(); // 用户不存在或密码不匹配
            }

            // 生成 JWT 和刷新令牌
            var token = GenerateJwtToken(user);
            var refreshToken = GenerateRefreshToken();
            RefreshTokens[model.Username] = refreshToken;

            // 返回令牌
            return Ok(new { token, refreshToken });
        }

        private bool VerifyPassword(string inputPassword, string storedHashedPassword)
        {
            // 使用相同的哈希算法验证密码
            using (var sha256 = SHA256.Create())
            {
                var hashedInput = Convert.ToBase64String(sha256.ComputeHash(Encoding.UTF8.GetBytes(inputPassword)));
                return hashedInput == storedHashedPassword;
            }
        }

        private string GenerateJwtToken(User user)
        {
            // 构建密钥和签名凭据
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            // 构建 Claims
            var claims = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()) // 使用数据库主键作为标识
            };

            // 创建 JWT Token
            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.Now.AddDays(3),
                signingCredentials: creds
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }


        private string GenerateRefreshToken()
        {
            return Guid.NewGuid().ToString("N");
        }

        [HttpPost("refresh-token")]
        [AllowAnonymous]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        [ProducesDefaultResponseType]
        public IActionResult RefreshToken([FromBody] RefreshTokenModel model)
        {
            // 验证刷新令牌是否存在并匹配
            if (!RefreshTokens.TryGetValue(model.Username, out var storedRefreshToken) || storedRefreshToken != model.RefreshToken)
            {
                return Unauthorized(); // 刷新令牌无效
            }

            // 从数据库中查找用户
            var user = _collection.Find(u => u.UserName == model.Username).FirstOrDefault();
            if (user == null)
            {
                return NotFound(); // 用户不存在
            }

            // 生成新的 JWT 和刷新令牌
            var newToken = GenerateJwtToken(user);
            var newRefreshToken = GenerateRefreshToken();
            RefreshTokens[model.Username] = newRefreshToken;

            // 返回新的令牌
            return Ok(new { token = newToken, refreshToken = newRefreshToken });
        }
  
    }

    public class LoginModel
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }

    public class RefreshTokenModel
    {
        public string Username { get; set; }
        public string RefreshToken { get; set; }
    }
}